package com.xiaodou.mjf.infrastructure.payeco.encrypt;

import com.xiaodou.mjf.infrastructure.payeco.util.Base64;

import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Enumeration;

/**
 * @author: XieminQuan
 * @time : 2007-11-20 下午04:10:22
 * <p/>
 * DNAPAY
 */

public class RSA {

    private static final String ENCODING = "UTF-8";

    //私钥签名
    public static String sign(String data, String pfx_path, String key_pass) {

        try {

            RSAPrivateKey pbk = getPrivateKey(pfx_path, key_pass);

            // 用私钥对信息生成数字签名
            Signature signet = Signature.getInstance("MD5withRSA");
            signet.initSign(pbk);
            signet.update(data.getBytes(ENCODING));
            byte[] signed = signet.sign(); // 对信息的数字签名

            return Base64.encode(signed);

        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    //私钥签名
    public static String sign(String data, String pfxUTF8) {

        try {

            RSAPrivateKey pbk = getPrivateKeyByUTF8(pfxUTF8);

            // 用私钥对信息生成数字签名
            Signature signet = Signature.getInstance("MD5withRSA");
            signet.initSign(pbk);
            signet.update(data.getBytes(ENCODING));
            byte[] signed = signet.sign(); // 对信息的数字签名

            return Base64.encode(signed);

        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    //公钥加密
    public static String encrypt(String data, String pub_key) {

        try {

            KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(pub_key));
            RSAPublicKey pbk = (RSAPublicKey) rsaKeyFac.generatePublic(keySpec);

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, pbk);

            byte[] encDate = cipher.doFinal(data.getBytes(ENCODING));

            return Base64.encode(encDate);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    //公钥加密
    public static byte[] encrypt64(String data, String pub_key) {

        try {

            KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(pub_key));
            RSAPublicKey pbk = (RSAPublicKey) rsaKeyFac.generatePublic(keySpec);

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, pbk);

            byte[] encDate = cipher.doFinal(data.getBytes(ENCODING));

            return encDate;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //私钥解密
    public static String decrypt(String sign_msg, String pfx_path, String pfx_pass) {

        try {

            RSAPrivateKey pbk = getPrivateKey(pfx_path, pfx_pass);

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
            cipher.init(Cipher.DECRYPT_MODE, pbk);

            byte[] btSrc = cipher.doFinal(Base64.decode(sign_msg));

            return new String(btSrc, ENCODING);

        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    //私钥解密
    public static String decrypt(String sign_msg, String pfxUTF8) {

        try {

            RSAPrivateKey pbk = getPrivateKeyByUTF8(pfxUTF8);

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
            cipher.init(Cipher.DECRYPT_MODE, pbk);

            byte[] btSrc = cipher.doFinal(Base64.decode(sign_msg));

            return new String(btSrc, ENCODING);

        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    //公钥验签
    public static boolean verify(String data, String pub_key, String value) {

        try {
            byte[] bts_data = Base64.decode(data);
            byte[] bts_key = Base64.decode(pub_key);

            KeyFactory rsaKeyFac = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bts_key);
            RSAPublicKey pbk = (RSAPublicKey) rsaKeyFac.generatePublic(keySpec);

            Signature signetcheck = Signature.getInstance("MD5withRSA");
            signetcheck.initVerify(pbk);
            signetcheck.update(value.getBytes(ENCODING));

            return signetcheck.verify(bts_data);

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static RSAPrivateKey getPrivateKey(String keyPath, String passwd) throws Exception {

        try {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            FileInputStream fis = new FileInputStream(keyPath);

            char[] nPassword = null;
            if ((passwd == null) || passwd.trim().equals("")) {
                nPassword = null;
            } else {
                nPassword = passwd.toCharArray();
            }
            ks.load(fis, nPassword);
            fis.close();

            Enumeration enumq = ks.aliases();
            String keyAlias = null;
            if (enumq.hasMoreElements()) {
                keyAlias = (String) enumq.nextElement();
            }

            PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, nPassword);

            return (RSAPrivateKey) prikey;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static RSAPrivateKey getPrivateKeyByUTF8(String pfxUTF8) throws Exception {
        // 取得私钥
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(org.apache.commons.codec.binary.Base64.decodeBase64((pfxUTF8)));

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        // 生成私钥
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        return (RSAPrivateKey) privateKey;
    }

    public static RSAPublicKey getPublicKey(String keyPath, String passwd) throws Exception {

        try {
            KeyStore ks = KeyStore.getInstance("PKCS12");

            FileInputStream fis = new FileInputStream(keyPath);

            char[] nPassword = null;
            if ((passwd == null) || passwd.trim().equals("")) {
                nPassword = null;
            } else {
                nPassword = passwd.toCharArray();
            }
            ks.load(fis, nPassword);
            fis.close();

            Enumeration enumq = ks.aliases();
            String keyAlias = null;
            if (enumq.hasMoreElements()) {
                keyAlias = (String) enumq.nextElement();
            }

            Certificate cert = ks.getCertificate(keyAlias);

            PublicKey pubkey = cert.getPublicKey();

            return (RSAPublicKey) pubkey;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) throws Exception {
        String res = "UgsJSPLREWk+kyPSG8Z470tkurVYMO36L1C8cSQcVJV1Sn2QO01XZNFJDEi0V+CeFpm0v5kgwAp5PhFpSlt9jdTPmxk8SxT1qRk7wKS0FiGkzvmYX7ZIVfMTb0CpIsJovwNsWAFQk3V6L4kH7yVWE4BO+yqmHmPOJa9qXUPWrvbkV+egvNmL/8/XSAvV/ciXiz2qliu513nImCjI3QsJw9iBgm/UhrlpB4ofwgbJ6zB0Pud/we3X+Ta+8UMuef7uc3O3sniaqSBiyROvTWhVbpGokxG/HPrPZctKZ5WTgdeaeZbsfHC9aLUrLZMDSJ/3g0RGeA7oTD1qeKldx6p/K1OMpF4QxPVVfaiNgg9cjYNdXotBbkHtWmdJowRys0foPVT0ZTQNpI9gtHYlH1ytjVBHX9jBMVQF/K1JSSv7QJ9rfvkie8/yFpvDmyPw/++IrZW4Trvss9WPwayrJUE5IRpsL/1wJ2dS/viORd9UFUiCSEdvHZob6pmxcd7dtqD4tjVIKEwdUI+r5lC3ERUVxoepFcA/YY7P9bMMx8uJp7H1qEDEy1rwgx3rgbc+oZ2J2tRsLu3cF1jfB0qK5pe9VwMoFUkRsstdI6YtHRIEugzw/8JHKENjA9D6lb8RYcnIVWB5VeTCZV9jnNs6Zf0MJwn6HPjROIzLaRnn5uFc+Stwi7ZZOJttGwTKdwA3Nonix1ONa0ymHRt+r7sY/sZbt1PdGbJChcVqmFTAIuiwv8rkqoR2S1DQy/TbtUalEZeN0JP2EfJxdpDu04+BWwlcBtCT9hHycXaQ8/1WbmUvWHAJacAh7Pv6jALTYKVj1Znz2jnOjNbm3xBcOg7mR4jmR/EXJCtNe+7nN1KxCVPo3BVOPVk+nGcHz+u/X+lwqgZia3X6Nsiwr8jK9/+d4Wl0KVUSEGDYZCY58KoixLDRtcB4LvpBiiuM4Ze9cG8L4p/dKT3zeD19dNa4Se1AlSt2M/yy0cgLhjyYELvv2lAeWwOvUEiPIWFFjhC779pQHlsD0fPJsrGtU+85KxHtF0nrcxgbxONYeUp41JRZsiGHXJMSO6vohKXTNlnySyDr16fasuBaB+oOCzQOGgaC6jTH0b7b+bWexlOmBdClMiUei1OkPlOHAU/EMtYlymceYoR1G/aPFTX24k9yh1NmrE+iC1Ar8b+Fb4gWeMc1IDr5q9Yiv5awTlLCdcyCYdWAGkHXAmGylb12tMuInrwjRnCftHevDy0qbQT/kJVqqTpt4zg3pgzRDYS3BNw5J25lHgZhFHwooUj4IhiZh5oqljz1jdTLkMzW3CVIw1wQW/ZFIFAdkU3JwOEDZWE/ia/foLOvfENakz193T1CgCU2xrTLaJeApReYT6vu49YupFPX1nnWU7wmNHiOU6iMoCleatSBpinAK030oS0GF78PxAtoWP1uh5Jgi0RIc+4CC+6/HzsVDYcA8bRlb0rfX4ZijZYg+PXDzOkW/ySinhprOhnecJO5f7pIH/3BkiYQGwYrDPSTuX+6SB/9wZImEBsGKwz0gkhHbx2aG+pSGZx/ehKXbqrkBhKD1fk3oqfhRctSjVe+9yT8bAVLbA==|QbIB1MpQfj2NWNvvFEgk/pWrGgG5kk4lGQ0ljNgysk3ilQpA03iXvfptkT7mQH3Ji8mf0fbV3LWVmlhw8kWAx+Dri2wphEFfNSfUoFG20BKS/14At05eGHPh1VtDxH48MCJFXQRHt6s5DYF2TOFLsq9WWmhvXoEdas3jNfEDct0=";

//        String pfx_path = "C:\\yilian.pfx";
//        String pfx_pass = "11111111";

        String dna_pub_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqWSfUW3fSyoOYzOG8joy3xldpBanLVg8gEDcvm9KxVjqvA/qJI7y0Rmkc1I7l9vAfWtNzphMC+wlulpaAsa/4PbfVj+WhoNQyhG+m4sP27BA8xuevNT9/W7/2ZVk4324NSowwWkaqo1yuZe1wQMcVhROz2h+g7j/uZD0fiCokWwIDAQAB";//公钥
        //    private static String mer_pfx_key = "E:\\doc-xd\\payeco\\互联网金融_20150326\\代收付系统对接文档\\易联代收付平台接口接入文档v2.1.6及demo\\yilian.pfx";//私钥
        String mer_pfx_key = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKpZJ9Rbd9LKg5jM4byOjLfGV2kFqctWDyAQNy+b0rFWOq8D+okjvLRGaRzUjuX28B9a03OmEwL7CW6WloCxr/g9t9WP5aGg1DKEb6biw/bsEDzG5681P39bv/ZlWTjfbg1KjDBaRqqjXK5l7XBAxxWFE7PaH6DuP+5kPR+IKiRbAgMBAAECgYAfDloAkRxrRZhwRwnwglyNNI/DCdFGzM29Hrew6kujIQFZ3vPSBL3mb9/B7c6PhlGIpdpe/ywAIxw5GSMfG0XlQ6umgPSsxF6TaRCXkBE1B1QYn5L4jVgHkszTRMCXkTybtaxEqEh6nhA6Krj4Y5ki1wpDpwHToTUYwz3RHuxdgQJBAN8hkxIhQ0ERALsrOWRZoishT9Ci5BxUtCYwKKw4Und1w3ywvxT28kDO2tp8aZ9/JVcHcRW04I+MmS0ZEPzGYNECQQDDcRpeVL6DLC/+fWhsUK6PixSmfH+roZURpJXlRPmQlxQwluoaQ2b/KUouujycnsphXIIpWHCZenfrJrS1yB1rAkBgU/lPOWb0fyempil3xi55mj7/3mLGTFcdqWrVttb7Va7YdOF5Zob9LZBUBKQAxH5VTRQn/9d2gYdbbdfkmKwRAkEAljVaP7/AAE64wE4gMIc98kLBZ0duVDnGuR2WuvPtHuyObt2+JNtC0L8qLYmjRfhgsL2JqD85oyvV+Jvx7XhU6wJBALIT5T+T3HdFRXlRAH12X74VXOnfHZ79sU/NNDBBtRN2AKfNo/I9g9xV7hZiVGTWEuDK8NImWYBU33PejWCZdS8=";//私钥


        String xml = "<MSGBEAN><VERSION>2.1</VERSION><MSG_TYPE>100002</MSG_TYPE><BATCH_NO>zjw201504080001</BATCH_NO><USER_NAME>13760136514</USER_NAME><TRANS_STATE></TRANS_STATE><MSG_SIGN>";
        String sign = RSA.sign(xml, mer_pfx_key);
        System.out.println("sign===: " + sign);
//        if (true)
//            return;

        String msg_sign_enc = res.split("\\|")[0];
        System.out.println("msg_sign_enc: " + msg_sign_enc);
        String key_3des_enc = res.split("\\|")[1];
        System.out.println("key_3des_enc: " + key_3des_enc);
        byte[] bs = Base64.decode(key_3des_enc);
        System.out.println("key_3des_enc  decode =: " + Base64.encode(bs));
        System.out.println(decrypt(key_3des_enc, mer_pfx_key));

        //解密密钥
        String key_3des = RSA.decrypt(key_3des_enc, mer_pfx_key);

//		key_3des = Base64.encode(key_3des.getBytes("UTF-8"));


        //解密报文
        String msg_sign = TripleDes.decrypt(key_3des, msg_sign_enc);
        System.out.println("msg_sign: "+msg_sign);
    }
}
